package gxprod.androidai.functions;

import gxprod.androidai.AIActivity;
import gxprod.androidai.BubbleAdapter;
import gxprod.androidai.DataCollection;
import gxprod.androidai.fetch.FetchWeather;
import gxprod.androidai.fetch.FetchWeather.WeatherCondition;
import gxprod.androidai.regex.MatchResult;
import gxprod.androidai.regex.NamedPattern;
import gxprod.androidai.widgets.WeatherWidget;

import java.util.Date;

//   °  °  °  °  °  °  °

/**
 * Weather information. I've got this one also
 * @author Josh Maleszewski
 */
public class WeatherFunction extends Function {

	public Date time;

	private NamedPattern[] patterns = new NamedPattern[] {
			NamedPattern.compile("(show me|hows) the (weather|forcast)"),

			NamedPattern.compile("(will|is) (it|their be|the sun)( going to)? (rain|snow|hail|be sunny|shine) ([\\w]+)"),
			NamedPattern.compile("(will|is) (it|their be|the sun)( going to)? (rain|snow|hail|be sunny|shine)"),
			
			NamedPattern.compile("(will|do) i (need|want) (a )?((heavy |light |thick |thin |)umbreal|coat|jacket) ([\\w]+)"),
			NamedPattern.compile("(will|do) i (need|want) (a )?((heavy |light |thick |thin |)umbreal|coat|jacket)"),

			NamedPattern.compile("Is ((it|today) a good day|it good weather) (for|to)(( [\\w]+){1,3})"),
			
			NamedPattern.compile("(what is the temputure|how (hot|cold) is it)")
	};

	@Override
	public boolean execute(MatchResult match, BubbleAdapter adapter) {

		if(DataCollection.getWeather() == null) {
			
			String zip = DataCollection.getZipCode(AIActivity.get());
			
			AIActivity.get().manager.beginOperation(new FetchWeather(this, zip), match, adapter);
			return true;
		}

		String item;		
		WeatherCondition givenDate = DataCollection.getWeather().Later.get(1);	// TODO: based upon any date or relative day in the raw text.
		String dayName = "today";
		switch(match.MatchIndex) {

			case 0:
				adapter.say(DataCollection.getWeather().getTodayDescript());
				adapter.postUpdate();
				
				final WeatherWidget ww = new WeatherWidget(AIActivity.get(), AIActivity.get().switcher);
				AIActivity.get().ShowWidget(ww);
				AIActivity.get().runOnUiThread(new Runnable() {
					public void run() { ww.populate(DataCollection.getWeather()); }
				});
				break;
				

			case 1:
				dayName = match.Matcher.group(5);
				// TODO get weather model by day
			case 2:
				item = match.Matcher.group(4);

				if(item.equals("rain") | item.equals("snow")) {
					if(givenDate.willItRain())	adapter.output("There is a " + (int)givenDate.PrecipitationChance + "% chance of rain today");
					else 					adapter.output("It will not " + item + " today");
				} else if(item.contains("sun") | item.contains("shine")) {
					int cc = (int) (givenDate.CloudCover);
					String comment = getCommentOnPercent(cc, false);
					adapter.output(comment + ", there will be about " + cc + "% cloud cover today");					
				}
				break;
				

			case 3:
				dayName = match.Matcher.group(5);
				// TODO get weather model by day
			case 4:
				item = match.Matcher.group(4);
				if(item.matches("(coat|jacket)")) {
					int low =  givenDate.TempLowF;
					
					String header;
					
					if(low >= 80)     header = "No";
					else if(low > 70) header = "Probably not";
					else if(low > 50) header = "Maybe";
					else if(low > 30) header = "Probably";
					else if(low > 15) header = "Yes";
					else              header = "Definantly";
					
					adapter.output(header + ", the low for today is " + low + " degrees");
				}
				else if(item.equals("umbrella")) {
					int percip = (int) givenDate.PrecipitationChance;
					String comment = getCommentOnPercent(percip, false);
					
					if(percip < 5)	adapter.output("No, there's no chance of precipitation");
					else			adapter.output(comment + "there's a " + percip + " chance of " + dayName);
				}
				break;


			case 5:
				String text = "Its about " + DataCollection.getWeather().Now.getTemp() + " right now";
				String say = "Its about " + DataCollection.getWeather().Now.getTemp() + "degrees right now";
				adapter.output(text, say);
				break;

				/*
			case 6:
				item = match.Matcher.group(4);
				int high = today.TempHighF;
				int low = today.TempLowF;
				float percipChance = today.PrecipitationChance;
				String msg = "Yes";

				if(item.contains("kites")) {
					if(high > 100) msg = "No, it will be too hot";
					else if(low < 40) msg = "No, it will be too cold";
					else if(percipChance >= 0.35f) msg = "No, there is a good chance of rain";
					else if(today.WindSpeedMi > 10) msg = "No, it will be to windy";
					else if(today.WindSpeedMi < 2) msg = "No, there wont be enough wind";

				} else if(item.contains("beach") | item.contains("swim")) {
					if(low < 68) msg = "No, it will be too cold";
					else if(percipChance >= 0.4f) msg = "No, there's a good chance of rain";

				} else
					msg = "I dont know how to deturmine that yet";

				adapter.output(msg + "<br/><h5>source: <b>World Weather Online</b></h5>", msg);
				break;
				 */
			default:
				return false;
		}
		return true;
	}
	
	
	private String getCommentOnPercent(int percent, boolean isPositive) {
		if(isPositive) percent = 100 - percent;
		
		if(percent <= 5)	return "Definantly";
		if(percent <= 10)	return "Yes";
		if(percent <= 30)	return "Probably";
		if(percent <= 50)	return "Maybe";
		if(percent <= 85)	return "Probably not";
		return "No";
	}
	

	@Override
	public MatchResult isMatch(String statement) {
		return super.isMatch(statement, patterns, 0.84f);
	}

	@Override
	public boolean cullFunction(String statement) { 
		return statement.contains("weather") |
				statement.contains("forcast") |
				statement.contains("rain") |
				statement.contains("snow") |
				statement.contains("hail") |
				statement.contains("coat") |
				statement.contains("hot") |
				statement.contains("cold") |
				statement.contains("temputure") |
				statement.contains("jacket") |
				statement.contains("sun") |
				statement.contains("umbrella");
		// TODO: more.....
	}
}
